/**
 ******************************************************************************
 * @file	rd-keyboard.cpp
 * @brief	输入设备按键读取

 * ./rd-keyboard.elf -D /dev/input/event0
 * 按下按键后屏幕显示
 *	down     3e      KEY_F4
 *	press    3e      KEY_F4
 *	press    3e      KEY_F4
 *	press    3e      KEY_F4
 *	press    3e      KEY_F4
 *	up       3e      KEY_F4
 *
 *
 * - 2016-9-30,MenglongWu,MenglongWoo@aliyun.com
*/

#include <linux/input.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>

#include "key-name.h"
// #include "printl.h"
// #include "proginfo.h"
// #include "autoconfig.h"


#ifdef CONFIG_QT_PTY
	#include "qt.hpp"
	#include "pty/dlg-pty.h"
#endif

#ifdef CONFIG_QT_PTY
	#define TXT_RED    "<font color=red>"
	#define TXT_GREEN  "<font color=green>"
	#define TXT_BLUE   "<font color=blue>"
	#define TXT_NORMAL "</font>"
#else
	#define TXT_RED    C_RED
	#define TXT_GREEN  C_GREEN
	#define TXT_BLUE   C_BLUE
	#define TXT_NORMAL C_NORMAL
#endif





#ifdef __cplusplus
extern "C" {
#endif


//char *device   = "/dev/input/event0";			// 默认设备
char *device   = "/dev/input/event3";			// 默认设备
#ifdef CONFIG_QT_PTY
DlgPty *pg_pty = NULL;
#endif


static void print_usage(const char *prog)
{
	printf("Usage: %s [-D]\n", prog);
	puts("  -D --device   device to use (default /dev/input/event0)\n");
	exit(1);
}


void parse_opts(int argc, char *argv[])
{
	while (1) {
		static const struct option lopts[] = {
			{ "device",  1, 0, 'D' },
			{ NULL, 0, 0, 0 },
		};
		int c;

		c = getopt_long(argc, argv, "D:", lopts, NULL);

		if (c == -1) {
			break;
		}

		switch (c) {
		case 'D':
			device = optarg;
			break;
		default:
			print_usage(argv[0]);
			break;
		}
	}
}






void *thread_rdkeyboard(void *arg)
{
	int   fdinput          = 0;
	int   len              = 0;
	char *keystatus        = "unknow";
	char  str_console[128] = "";
	struct input_event event_status;
	static unsigned char joypad = 0;
	
	fdinput = open(device, O_RDONLY);
	if (fdinput < 0) {
		printf("fail open device %s\n", device);
		return 0;
	}


	while(1) {
		len = read(fdinput, &event_status, sizeof(event_status));
		if (len != -1)  {
			printf("type %x code %x value %x\r\n", event_status.type, event_status.code,  event_status.value);
		}
		if (len != -1 && event_status.type == EV_KEY) {
			switch(event_status.value) {
			case 1:
				keystatus =     "down"  ;
				break;
			case 2:
				keystatus =   "press" ;
				break;
			case 0:
				keystatus =  "up"    ;
				break;
			default:
				keystatus = "unknow";
				printf("code %x %x %x\n", event_status.code, event_status.value, event_status.type);
				break;
			}
#ifdef CONFIG_QT_PTY
			snprintf(str_console , sizeof(str_console),
			         "<pre>%s\t%x\t%s<br></pre>",
			         keystatus,
			         event_status.code,
			         disp_keyname(event_status.code));
			pg_pty->insertColor(str_console);
#else
			snprintf(str_console , sizeof(str_console),
			         "%s\t%x\t%s\r\n",
			         keystatus,
			         event_status.code,
			         disp_keyname(event_status.code));
			printf("[%x]\r\n", event_status.code);
			printf("%s", str_console);
#endif

            /**
             * FC手柄 bit 键位对应关系 真实手柄中有一个定时器，处理 连A  连B 
             * 0  1   2       3       4    5      6     7
             * A  B   Select  Start  Up   Down   Left  Right
             */
            #define JOY_A       (1 << 0)
            #define JOY_B       (1 << 1)
            #define JOY_SELECT  (1 << 2)
            #define JOY_START   (1 << 3)
            #define JOY_UP      (1 << 4)
            #define JOY_DOWN    (1 << 5)
            #define JOY_LEFT    (1 << 6)
            #define JOY_RIGHT   (1 << 7)

            if (event_status.value == 1 || event_status.value == 2) {
                switch(event_status.code) {
                case KEY_F3:// SELECT
                    joypad |= JOY_SELECT;
                    break;
                case KEY_F5:// START
                    joypad |= JOY_START;
                    break;
                case KEY_SPACE:// A
                    joypad |= JOY_A;
                    break;
                case KEY_TAB:// B
                    joypad |= JOY_B;
                    break;
                case KEY_LEFT:
                    joypad |= JOY_LEFT;
                    break;
                case KEY_RIGHT:
                    joypad |= JOY_RIGHT;
                    break;
                }
            }


            if (event_status.value == 0) {
                switch(event_status.code) {
                case KEY_F3:// SELECT
                    joypad &= ~JOY_SELECT;
                    break;
                case KEY_F5:// START
                    joypad &= ~JOY_START;
                    break;
                case KEY_SPACE:// A
                    joypad &= ~JOY_A;
                    break;
                case KEY_TAB:// B
                    joypad &= ~JOY_B;
                    break;
                case KEY_LEFT:
                    joypad &= ~JOY_LEFT;
                    break;
                case KEY_RIGHT:
                    joypad &= ~JOY_RIGHT;
                    break;
                }
            }
            // printf("joy %x\r\n", joypad);
		}
	}
	close(fdinput);
}

#ifdef CONFIG_QT_PTY
int main(int argc, char *argv[])
{
	QApplication app(argc, argv);
	static pthread_t g_readtimeout;

	pg_pty = new DlgPty;
	parse_opts(argc, argv);
	pthread_create(&g_readtimeout, NULL, thread_rdkeyboard, NULL);
	pg_pty->show();
	app.exec();

	exit(4);
}

#else
int main(int argc, char *argv[])
{
	// parse_opts(argc, argv);
	thread_rdkeyboard(NULL);
}
#endif




#ifdef __cplusplus
}
#endif
